package com.brillilab.service.logic.inventory;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import com.brillilab.service.quartz.BrillQuartzScheduler;
import com.brillilab.domain.enums.hardware.LockOperationEnum;
import com.brillilab.domain.enums.hardware.LockStateEnum;
import com.brillilab.domain.po.hardware.HardWareOperateRecord;
import com.brillilab.domain.po.hardware.LockOperation;
import com.brillilab.service.core.hardware.IHardwareOperateRecordService;
import com.brillilab.service.core.hardware.ILockOperationService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import com.brillilab.common.utils.MyBeanUtils;
import com.brillilab.domain.enums.space.BoxTypeEnum;
import com.brillilab.domain.po.inventory.ReagentInventory;
import com.brillilab.domain.po.kit.Kit;
import com.brillilab.domain.po.kit.KitSpec;
import com.brillilab.domain.po.space.Box;
import com.brillilab.domain.po.space.Panel;
import com.brillilab.domain.po.space.PanelGridUsed;
import com.brillilab.domain.vo.inventory.KitInventoryDeleteVo;
import com.brillilab.domain.vo.kit.KitDeleteList;
import com.brillilab.domain.vo.print.KitInventoryPrintVo;
import com.brillilab.domain.vo.user.UserInfoVo;
import com.brillilab.service.core.kit.IKitService;
import com.brillilab.service.core.kit.IKitSpecService;
import com.brillilab.service.core.kit.IReagentTypeService;
import com.brillilab.service.core.space.IBoxService;
import com.brillilab.service.core.space.IPanelService;
import com.brillilab.service.core.system.IDictService;

import javax.annotation.Resource;

/**
 * 试剂库存删除
 * @author xuzue
 **/
@Service
@Transactional
public class InventoryDeleteLogic {
    @Resource
    private ReagentInventoryLogic reagentInventoryLogic;
    @Resource
    private IKitService kitService;
    @Resource
    private IKitSpecService kitSpecService;
    @Resource
    private IReagentTypeService reagentTypeService;
    @Resource
    private IDictService dictService;
    @Resource
    private IPanelService panelService;
    @Resource
    private IBoxService boxService;
    @Resource
    private IHardwareOperateRecordService hardwareOperateRecordService;
    @Resource
    private ILockOperationService lockOperationService;
    @Resource
    private BrillQuartzScheduler scheduler;
    
    /**
     * 删除试剂库存列表
     */
    public List<KitDeleteList> getKitInventoryDeleteList(Long kitId,UserInfoVo userInfoVo){
        Assert.isTrue(kitId!=null && userInfoVo!=null,"请求参数缺失！");
        Kit kit=kitService.selectById(kitId);
        Assert.isTrue(kit != null && kit.getLabId().equals(userInfoVo.getLabId()), "您没有操作权限");
        List<KitDeleteList> kitDeleteLists=new ArrayList<KitDeleteList>();
       
        List<ReagentInventory> reagentInventoryList=reagentInventoryLogic.getReagentInventoryDeleteList(kitId,userInfoVo);
        if(!CollectionUtils.isEmpty(reagentInventoryList)){
        	List<Long> deviceIds=reagentInventoryList.stream().map(ReagentInventory::getDeviceId).distinct().collect(Collectors.toList());
        	List<Long> specIdList=reagentInventoryList.stream().map(ReagentInventory::getKitSpecId).distinct().collect(Collectors.toList());
        	Long[] specIds=specIdList.toArray(new Long[specIdList.size()]);
        	List<KitSpec> kitSpecList=kitSpecService.selectListByIds(kitId,specIds);
        	Map<Integer, String> zoneMap=dictService.getZoneMap();
        	Map<Integer, String> unitMap=dictService.getUnitMap();
        	Map<Long, Panel> panelCache = new HashMap<>();
        	List<Long> boxIdList = reagentInventoryList.stream().filter(i -> i.getBoxId() != null).map(ReagentInventory::getBoxId).distinct().collect(Collectors.toList());
            List<Box> boxList = boxService.listByIdList(boxIdList);
            List<Long> reagentTypeIdList = reagentInventoryList.stream().filter(i -> i.getReagentTypeId() != null).map(ReagentInventory::getReagentTypeId).distinct().collect(Collectors.toList());
            Map<Long, Long> firstReagentTypeMap = reagentTypeService.selectFirstReagentTypeMap(reagentTypeIdList);

            List<HardWareOperateRecord> locks = hardwareOperateRecordService.selectLockListByDeviceIds(deviceIds);
            deviceIds.forEach(id ->{
                KitDeleteList kitDeleteList = new KitDeleteList();
                List<ReagentInventory> inventoryList=reagentInventoryList.stream().filter(r -> r.getDeviceId() != null && r.getDeviceId().equals(id)).collect(Collectors.toList());
                if(!CollectionUtils.isEmpty(inventoryList)){
                    ReagentInventory reagentInventory=inventoryList.get(0);
                    HardWareOperateRecord lock=locks.stream().filter(e -> e.getDeviceId().equals(id)).findFirst().orElse(null);
                    if(lock!=null){
                        kitDeleteList.setHasLock(true);
                    }else {
                        kitDeleteList.setHasLock(false);
                    }
                    kitDeleteList.setDeviceId(reagentInventory.getDeviceId());
                    kitDeleteList.setRoomName(reagentInventory.getRoomName());
                    kitDeleteList.setZoneName(zoneMap.get(reagentInventory.getZone()));
                    kitDeleteList.setDeviceIndex(reagentInventory.getDeviceIndex());
                    kitDeleteList.setDevice(reagentInventory.getRoomName() + "->" + reagentInventory.getDeviceIndex() + "[" + zoneMap.get(reagentInventory.getZone()) + "]");
                    List<KitInventoryDeleteVo> kitInventoryDeleteVos = new ArrayList<KitInventoryDeleteVo>();
                    inventoryList.forEach(k -> {
                        KitInventoryDeleteVo deleteVo = new KitInventoryDeleteVo();
                        MyBeanUtils.copyProperties(k, deleteVo);
                        deleteVo.setTakeAmount(k.getAmount());
                        deleteVo.setUnitName(unitMap.get(k.getUnit()));
                        deleteVo.setKitDevice(k.getPanelName() + (k.getBoxColor() == null ? "" : ">" + k.getBoxColor() + ">" + k.getGridRow() + k.getGridColumn()));
                        deleteVo.setZoneName(zoneMap.get(deleteVo.getZone()));
                        deleteVo.setFirstReagentTypeId(firstReagentTypeMap.get(k.getReagentTypeId()));
                        kitSpecList.forEach(spec -> {
                            if (spec.getId().equals(deleteVo.getKitSpecId())) {
                                deleteVo.setSize(spec.getSize());
                            }
                        });
                        
                        Panel thisPanel = panelCache.get(k.getPanelId());
                        if (thisPanel == null) {
                            thisPanel = panelService.get(k.getPanelId());
                            panelCache.put(thisPanel.getId(), thisPanel);
                        }
                        deleteVo.setPanelRows(thisPanel.getRows());
                        deleteVo.setPanelColumns(thisPanel.getColumns());
                        deleteVo.setIsSingleBox(false);
                        if (k.getBoxId() != null) {
                            Optional<Box> boxOpt = boxList.stream().filter(b -> b.getId().equals(k.getBoxId())).findFirst();
                            if (boxOpt.isPresent()) {
                                if (boxOpt.get().getRows() == 1 && boxOpt.get().getColumns() == 1) {
                                	deleteVo.setIsSingleBox(true);
                                }
                            }
                        }
                        if (k.getKitBoxId() != null) {
                            List<PanelGridUsed> panelGridUsedList = panelService.getPanelGridUsedListByBoxId(k.getKitBoxId(), BoxTypeEnum.KIT_BOX);
                            deleteVo.setGridUsedList(panelGridUsedList);
                        }

                        kitInventoryDeleteVos.add(deleteVo);
                    });
                    kitDeleteList.setDeleteVoList(kitInventoryDeleteVos);
                    kitDeleteLists.add(kitDeleteList);
                }
            });
        }

        for (KitDeleteList kitTakeDeviceList: kitDeleteLists){

            HardWareOperateRecord lock=hardwareOperateRecordService.selectLockByDeviceId(kitTakeDeviceList.getDeviceId());
            if(lock!=null){
                LockOperation lockOperation = lockOperationService.selectDeleteOperation(kitTakeDeviceList.getDeviceId(),userInfoVo.getLabMemberId(),LockOperationEnum.UNLOCK.getValue());
                if(lockOperation!=null && lockOperation.getOperate().equals(LockOperationEnum.UNLOCK.getValue())){
                    Date nextFireTime=scheduler.getNextFireTime(lockOperation.getJobName(),lockOperation.getJobGroup());
                    long time;
                    if(nextFireTime != null){
                        time = nextFireTime.getTime() - System.currentTimeMillis();
                    }else {
                        time = 0L;
                    }
                    kitTakeDeviceList.setTime(time);
                    if(time < 1000){
                        kitTakeDeviceList.setLockerState(LockStateEnum.END.getValue());
                    }else {
                        kitTakeDeviceList.setLockerState(LockStateEnum.UNLOCK.getValue());
                    }
                }else {
                    kitTakeDeviceList.setTime(5 * 60 *1000L);
                    kitTakeDeviceList.setLockerState(LockStateEnum.LOCK.getValue());
                }
            }else {
                kitTakeDeviceList.setTime(5 * 60 *1000L);
                kitTakeDeviceList.setLockerState(LockStateEnum.NULL.getValue());
            }
        }


        return kitDeleteLists;
    }
    
    public KitInventoryPrintVo getKitInventoryPrintVo(Long kitId,UserInfoVo userInfoVo){
    	List<ReagentInventory> reagentInventoryList=reagentInventoryLogic.getReagentInventoryDeleteList(kitId,userInfoVo);
    	List<KitDeleteList> kitDeleteLists = this.getKitInventoryDeleteList(kitId, userInfoVo);
    	 KitInventoryPrintVo PrintVo=new KitInventoryPrintVo();
         PrintVo.setUsageTime(new Date());
         PrintVo.setUserName(userInfoVo.getName());
         PrintVo.setNum(reagentInventoryList.size());
         PrintVo.setKitDeleteLists(kitDeleteLists);
         return PrintVo;
    }

    /**
     * 删除试剂库存并打印清单
    */
    public KitInventoryPrintVo deleteKitInventory(Long kitId,UserInfoVo userInfoVo){
        KitInventoryPrintVo PrintVo= this.getKitInventoryPrintVo(kitId, userInfoVo);
        boolean isDelete=reagentInventoryLogic.deleteKitInventory(kitId);
        if(isDelete){
            return PrintVo;
        }else{
            return null;
        }
    }


}
